package com.guardchina.framework.redis;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.Arrays;

/**
 * 描述：redis spring bean 配置类
 *
 * @author lwb
 * @date 2019/4/12 9:25
 */
@Configuration
@EnableCaching
public class RedisConfiguration extends CachingConfigurerSupport {

   @Bean
   public RedisTemplate redisTemplate(RedisConnectionFactory factory){
       RedisTemplate redisTemplate = new RedisTemplate();
       redisTemplate.setConnectionFactory(factory);
       RedisSerializer redisSerializer = new StringRedisSerializer();
       redisTemplate.setKeySerializer(redisSerializer);
       redisTemplate.setHashKeySerializer(redisSerializer);
       redisTemplate.setValueSerializer(redisSerializer);
       redisTemplate.setHashValueSerializer(redisSerializer);
       return redisTemplate;
   }

    @Bean
    @Override
    public KeyGenerator keyGenerator(){
        return (target, method, params)->{
          StringBuilder sb = new StringBuilder();
          sb.append(target.getClass().getName())
                  .append(":")
                  .append(method.getName());
          return Arrays.stream(params)
                  .reduce((a, b) -> a + "-" + b)
                  .map(s -> sb.append(":").append(s))
                  .map(StringBuilder::toString)
                  .orElse(sb.toString());
        };
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory){
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory);

        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(
                        RedisSerializationContext.SerializationPair
                        .fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(
                        RedisSerializationContext.SerializationPair
                        .fromSerializer(new StringRedisSerializer())
                );
        return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
    }

}
